package com.jfm.jfmc.plugin.udp.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;

/**
 * @author DYang
 * @since 2024-10-11 23:05
 */
@Slf4j
public class UDPUtil {

    private static final byte[] DEFAULT_CONTENT = "hello".getBytes(StandardCharsets.UTF_8);

    /**
     * convert 16 hexString to byte[]
     * eg: 302c0201010409636f6d6d756e697479a11c020419e502e7020100020100300e300c06082b060102010102000500
     * 16进制字符串不区分大小写，返回的数组相同
     * @param hexString 16 hexString
     * @return byte[]
     */
    public static byte[] fromHexString(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }
        byte[] bytes = new byte[hexString.length() / 2];
        String hex;
        for (int i = 0; i < hexString.length() / 2; i++) {
            hex = hexString.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(hex, 16);
        }
        return bytes;
    }

    /**
     * 测试UDP 端口是否可用，超时抛出异常则认为端口不通，默认超时5秒
     * @param host 主机
     * @param port 端口
     * @param timeout 毫秒（ms）
     * @return
     */
    public static boolean isAvailable(String host, int port,int timeout,String content) {
        try (DatagramSocket socket = new DatagramSocket()) {
            socket.setSoTimeout(timeout);
            byte[] buffer = fromHexString(content);
            buffer = buffer == null ? DEFAULT_CONTENT : buffer;
            SocketAddress socketAddress = new InetSocketAddress(host, port);
            DatagramPacket request = new DatagramPacket(buffer, buffer.length, socketAddress);
            socket.send(request);
            byte[] responseBuffer = new byte[1];
            DatagramPacket response = new DatagramPacket(responseBuffer, responseBuffer.length);
            socket.receive(response);

            return true;
        } catch (IOException e) {
            log.error("udp check error", e);
        }
        return false;
    }
}
